﻿//using System;
//using System.Collections.Concurrent;
//using System.Net;
//using System.Reactive.Disposables;
//using nRoute.Components.Composition.Adapters;
//using nRoute.Components.Mapping;

//namespace nRoute.Components.Composition
//{
//    public partial class ServiceCatalog
//        : IDisposable
//    {
//        private readonly ConcurrentBag<PendingMapping> _pendingMappings;
//        private readonly ChannelObserver<MappedAssemblyInfo> _assemblyObserver;

//        private IDisposable AutoMapAssemblies()
//        {
//            _assemblyObserver = new ChannelObserver<MappedAssemblyInfo>(OnAssemblyMapped);

//            return Disposable.Empty;
//        }

//        public void RegisterKnownAdapters()
//        {
//            // and register built-in adapters
//            KnownAdapters.RegisterAdapters();
//        }

////#region Assembly Mapping Related

////#if (WINRT)
////        internal static async Task Initialize()
////        {
////            lock (_lock)
////            {
////                _assemblyObserver.Subscribe(true);
////            }
////            await AssemblyMapper.MapApplicationAssemblies();
////        }
////#else
////        internal static void Initialize()
////        {
////            lock (_lock)
////            {
////                _assemblyObserver.Subscribe(true);
////                AssemblyMapper.MapApplicationAssemblies();
////            }
////        }
////#endif

////#endregion

//#region Public Methods
        
//        // For Unresolved Mapping

//        public static void ThrowIfHasUnresolvedMapping()
//        {
//            lock (_lock)
//            {
//                if (_pendingMappings.Count > 0)
//                {
//                    throw new UnresolvedMappingsException(_pendingMappings[0].TargetType,
//                        _pendingMappings[0].ResourceAttribute.GetType());
//                }
//            }
//        }

//#endregion

//#region Nested Classes

//        private class PendingMapping
//        {
//            public PendingMapping(MapResourceBaseAttribute resourceAttribute, Type targetType)
//            {
//                ResourceAttribute = resourceAttribute;
//                TargetType = targetType;
//            }

//            public MapResourceBaseAttribute ResourceAttribute {get; set; }

//            public Type TargetType {get; set; }
//        }

//#endregion

//#region Helpers

//        private void OnAssemblyMapped(MappedAssemblyInfo info)
//        {
//            if (info == null || info.Assembly == null) return;

//            // else we load
//            lock (_lock)
//            {
//                // we first look for given known type of resources
//                AssemblyMapper.GetAttributesInMappedAssembly<MapAsKnownResourceAttribute>(info.Assembly, (a, t) =>
//                {
//                    if (a == null) return;
//                    a.RegisterResource(t);
//                });

//                // we map every attribute - note_, a is the attribute instance and t is type it is applied on
//                AssemblyMapper.GetAttributesInMappedAssembly<MapResourceBaseAttribute>(info.Assembly, (a, t) =>
//                {
//                    // we get the attribute, and use it resolve 
//                    if (a == null) return;

//                    // we check if all things are resolved
//                    if (a.CanInitialize(t))
//                    {
//                        CatalogResource(a, t);
//                    }
//                    else
//                    {
//                        _pendingMappings.Add(new PendingMapping(a, t));
//                    }

//                });

//                // we check if any there are any pending items and as to if they can be resolved
//                if (_pendingMappings.Count > 0)
//                {

//                    bool _isResolving = false;
//                    while (true)
//                    {
//                        var _resourceMappings = _pendingMappings.ToArray();
//                        foreach (var _resourceMapping in _resourceMappings)
//                        {
//                            // if it can 
//                            if (_resourceMapping.ResourceAttribute.CanInitialize(_resourceMapping.TargetType))
//                            {
//                                CatalogResource(_resourceMapping.ResourceAttribute, _resourceMapping.TargetType);
//                                _pendingMappings.Remove(_resourceMapping);
//                                _isResolving = true;
//                            }
//                        }

//                        // if not even one entity was resolved then we return
//                        if (!_isResolving) break;
//                        _isResolving = false;
//                    }
//                }

//#if DEBUG && WRITETOCONSOLE
//                Debug.WriteLine(string.Format("Pending mapping {0}", _pendingMappings.Count));
//#endif
//            }
//        }

//#endregion

//    }
//}
